package com.as3xls
{
	import com.as3xls.xls.ExcelFile;
	import com.as3xls.xls.Sheet;
	
	import flash.errors.IllegalOperationError;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.utils.ByteArray;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.collections.XMLListCollection;
	import mx.controls.Alert;
	import mx.controls.DataGrid;
	
	public class FlexToExcel
	{
		public function FlexToExcel()
		{
			throw new IllegalOperationError ("Clase \"ExcelExporterUtil\" es estática. No puede crear la instancia");
		}
		
		/** 
		 *  
		 * Exporta los datos de un datagrid hacia un Excel. 
		 * Toma el dataProvider del mismo y las columnas para su exportacion 
		 *  
		 * @param dg          Referencia al datagrid 
		 * @defaultName         Nombre default con el que se va a generar el archivo excel 
		 *  
		 */ 
		static public function dataGridExporter(dg:DataGrid, defaultName:String):void 
		{ 
			try
			{
				if (dg == null || dg.dataProvider == null || defaultName == null || defaultName == "") 
					return; 
				
				var cols:Number = 0; 
				var colsValues:Array = []; 
				var cantCols:Number = dg.columnCount; 
				var fieldT:String; 
				var headerT:String; 
				
				// armo el listado de headers y variables para cada columna 
				for ( ; cols < cantCols; cols++) 
				{ 
					headerT = (dg.columns[cols] as Object).headerText 
					fieldT = (dg.columns[cols] as Object).dataField; 
					if ( fieldT == null || fieldT == "" || headerT == null || headerT == "") 
						continue;  
					colsValues.push({ 
						header:headerT, 
						value:fieldT 
					}); 
				} 
				
				if ( colsValues.length == 0 ) 
					return; 
				
				defaultName = defaultName.search(".xls") == -1 ? defaultName + ".xls" : defaultName; 
				export(dg.dataProvider, colsValues, defaultName);
			}
			catch (error:Error)
			{
				Alert.show(error.message);
			}
		}
		
		/** 
		 *  
		 * Export to Excel 
		 *  
		 * @param obj          Objeto simple, XML, XMLList, Array, ArrayCollection o XMLListCollection 
		 *                   que se quiere exportar a excel 
		 * @colsValues         Listado de objetos que indican cual es el nombre de la columna 
		 *                   y que propiedad del objeto se utiliza para sacar los datos de la columna 
		 *                   {header:"nombre del header", value:"propiedad del objeto que contiene el valor"} 
		 * @param defaultName   Nombre default con el que se genera el excel 
		 *  
		 */ 
		static public function export(obj:Object, colsValues:Array, defautlName:String):void 
		{  
			try
			{	  
				var _dp:ICollectionView = getDataProviderCollection(obj);
				
				if ( _dp == null ) 
					return; 
				
				var rows:Number = 0; 
				var cols:Number = 0; 
				var cantCols:Number = colsValues.length; 
				var sheet:Sheet = new Sheet(); 
				sheet.resize(_dp.length + 1, colsValues.length); 
				
				for ( ; cols < cantCols; cols++) 
				{ 
					sheet.setCell(rows, cols, colsValues[cols].header); 
				} 
				
				cols = 0;         
				rows++;
				
				var cursor:IViewCursor = _dp.createCursor();
				
				var numRegistros:int = _dp.length;
				var i:int = 0;
				for (i = 0; i < numRegistros; i++){
					for (cols = 0 ; cols < cantCols; cols++) 
					{ 
						if ((cursor.current as Object).hasOwnProperty(colsValues[cols].value) )
						{
							//sheet.setCell(i + 1, cols, (cursor.current as Object)[colsValues[cols].value]);
							//var value:Object = (cursor.current as Object)[colsValues[cols].value];
							//sheet.setCell(rows, cols, value);
							sheet.setCell(rows, cols, (cursor.current as Object)[colsValues[cols].value]);				   				                  	
						}                      
					}             
					rows++; 
					cursor.moveNext(); 
				}
				
				var xls:ExcelFile = new ExcelFile(); 
				xls.sheets.addItem(sheet); 
				var bytes:ByteArray = xls.saveToByteArray(); 
				
				var fr:FileReference = new FileReference();		 
				fr.save(bytes, defautlName); 
			}
			catch(error:Error)
			{
				Alert.show(error.message);
			}
		}
		
		/** 
		 *  
		 * A partir de un elemento pasado se genera un ICollectionView 
		 * para su correcto recorrido 
		 *  
		 * @param obj         Objeto a convertir a ICollectionView 
		 *  
		 *  
		 * @return referencia a un ICollectionView.  
		 *  
		 */ 
		static public function getDataProviderCollection(obj:Object):ICollectionView 
		{ 
			if ( (obj is Number && isNaN(obj as Number)) || (!(obj is Number) && obj == null)) 
			{ 
				return null; 
			} 
			else if ( obj is ICollectionView ) 
			{ 
				return obj as ICollectionView; 
			} 
			else if ( obj is Array ) 
			{ 
				return new ArrayCollection(obj as Array); 
			} 
			else if ( obj is XMLList ) 
			{ 
				return new XMLListCollection(obj as XMLList); 
			} 
			else if ( obj is XML ) 
			{ 
				var col:XMLListCollection = new XMLListCollection(); 
				col.addItem(obj); 
				return col; 
			} 
			else if ( obj is Object ) 
			{ 
				return new ArrayCollection([obj]); 
			} 
			else 
			{ 
				return null; 
			} 
		} 
		
	}
}